/*
 * SnapshotVehicle.java
 * 
 * Created by demory on Mar 18, 2009, 9:47:33 PM
 * 
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.fpdev.apps.admin.analysis;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.fpdev.apps.admin.analysis.VisualizedRun;
import org.fpdev.apps.admin.gui.ACGUI;
import org.fpdev.apps.admin.gui.map.MapCanvas;
import org.fpdev.apps.admin.gui.map.MapDrawable;
import org.fpdev.apps.admin.gui.map.PointOfInterest;

/**
 *
 * @author demory
 */
public class VisualizedVehicle implements MapDrawable, PointOfInterest {

  private ACGUI gui_;
  private VisualizedRun ri_;

  private Point2D.Double[] wLocs_;
  private double[] thetas_;
  private double length_, width_;
  private Color drawColor_;

  private int screenX_, screenY_; // the vehicle's screen coordinates for the current canvas

  public VisualizedVehicle(ACGUI gui, VisualizedRun ri, Point2D.Double[] locations, double[] thetas, double length, double width) {
    gui_ = gui;
    ri_ = ri;
    wLocs_ = locations;
    thetas_ = thetas;
    length_ = length;
    width_ = width;
    drawColor_ = getColor();
  }

  private Color getColor() {
    switch(ri_.getSubRoute().getPath().getType()) {
      case BUS: return Color.blue;
      case METRO: return new Color(128,0,0);
      case LIGHTRAIL: return Color.green;
      case REGIONALRAIL: return Color.gray;
    }
    return Color.BLACK;
  }
  public void draw(MapCanvas canvas) {
    for(int i=0; i < wLocs_.length; i++)
      drawVehicle(canvas, wLocs_[i].x, wLocs_[i].y, thetas_[i], 2, (i == 0));
  }

  @SuppressWarnings("empty-statement")
  public void drawVehicle(MapCanvas canvas, double wx, double wy, double theta, int borderWidth, boolean point) {

    double mx = canvas.getCC().xToScreen(wx);
    double my = canvas.getCC().yToScreen(wy);

    double sintheta = Math.sin(theta);
    double costheta = Math.cos(theta);

    // "front" offset point
    double fMult = point ? .2 : .5;
    double txf = mx + (length_ * fMult) * costheta, tyf = my - (length_* fMult) * sintheta;
    
    // "back" offset point:
    double txb = mx - (length_ / 2) * costheta, tyb = my + (length_ / 2) * sintheta;

    //double width = len * .6;

    double tx1 = txf + (width_ / 2) * Math.cos(theta - Math.PI / 2), ty1 = tyf - (width_ / 2) * Math.sin(theta - Math.PI / 2);
    double tx2 = mx + (length_ / 2) * costheta, ty2 = my - (length_ / 2) * sintheta;
    double tx3 = txf + (width_ / 2) * Math.cos(theta + Math.PI / 2), ty3 = tyf - (width_ / 2) * Math.sin(theta + Math.PI / 2);

    double tx4 = txb + (width_ / 2) * Math.cos(theta + Math.PI / 2), ty4 = tyb - (width_ / 2) * Math.sin(theta + Math.PI / 2);
    double tx5 = txb + (width_ / 2) * Math.cos(theta - Math.PI / 2), ty5 = tyb - (width_ / 2) * Math.sin(theta - Math.PI / 2);

    int[] xArr, yArr;
    if(point) {
      xArr = new int[] {(int) tx1 + 1, (int) tx2 + 1, (int) tx3 + 1, (int) tx4 + 1, (int) tx5 + 1};
      yArr = new int[] {(int) ty1 + 1, (int) ty2 + 1, (int) ty3 + 1, (int) ty4 + 1, (int) ty5 + 1};
    }
    else {
      xArr = new int[] {(int) tx1 + 1, (int) tx3 + 1, (int) tx4 + 1, (int) tx5 + 1};
      yArr = new int[] {(int) ty1 + 1, (int) ty3 + 1, (int) ty4 + 1, (int) ty5 + 1};
    }
    Graphics2D g2d = canvas.getGraphics();

    g2d.setColor(drawColor_);
    g2d.fillPolygon(xArr, yArr, point ? 5 : 4);

    if (borderWidth > 0) {
      g2d.setStroke(new BasicStroke(borderWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
      g2d.setColor(Color.WHITE);
      g2d.drawPolygon(xArr, yArr, point ? 5 : 4);
    }

    //g2d.setColor(Color.BLACK);
    //g2d.drawString("t="+(360*theta_/(2*Math.PI)) , (int) mx, (int) my);

    screenX_ = (int) mx;
    screenY_ = (int) my;

  }

  public Rectangle2D getBoundingBox() {
    double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
    double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
    for (int i = 0; i < wLocs_.length; i++) {
      minX = Math.min(minX, wLocs_[i].x);
      minY = Math.min(minY, wLocs_[i].y);
      maxX = Math.max(maxX, wLocs_[i].x);
      maxY = Math.max(maxY, wLocs_[i].y);
    }
    return new Rectangle2D.Double(minX-length_, minY-length_, (maxX-minX)+length_*2, (maxY-minY)+length_*2);
  }

  public int getScreenX() {
    return screenX_;
  }

  public int getScreenY() {
    return screenY_;
  }

  public void mouseOver(int mx, int my) {
    gui_.statusText(ri_.getSubRoute().getMasterID()+" ("+ri_.getSubRoute().getRoute().getName()+"), run "+ri_.getRun());
    drawColor_ = Color.yellow;
    gui_.getMapPanel().refresh(false, false, true);
  }

  public void mouseOut() {
    gui_.statusText("");
    drawColor_ = Color.red;
    gui_.getMapPanel().refresh(false, false, true);
  }
}
